package com.leyou.auth.service.impl;

import com.leyou.auth.constants.JwtConstants;
import com.leyou.auth.constants.RedisConstants;
import com.leyou.auth.dto.UserDetail;
import com.leyou.auth.service.UserAuthService;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.CookieUtils;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.UserDTO;
import feign.FeignException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class UserAuthServiceImpl implements UserAuthService {

    @Autowired
    private UserClient userClient;


    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public void authLogin(String username, String password, HttpServletResponse response) {
        UserDTO userDTO;

        //1,请求user服务，根据用户名密码获取到userDTO
        try {
            userDTO = this.userClient.queryUserByNameAndPass(username, password);
        } catch (FeignException e) {
            //好处在于把错误不转换，原始状态码是多少，就返回多少，原始消息是什么就返回什么
            throw new LyException(e.status(), e.getMessage());
        }

        UserDetail userDetail = new UserDetail();

        //2,根据userDTO生成userDetail
        BeanUtils.copyProperties(userDTO, userDetail);


        //3,基于userDetail生成用户的token令牌信息
        //生成用户的令牌信息
        String token = jwtUtils.createJwt(userDetail);

        // 4.把JWT写入用户cookie
        writeCookie(response, token);

//        //把cookie响应
//        Cookie cookie = new Cookie("LY_TOKEN",token);
//
//        cookie.setDomain("leyou.com");
//
//        cookie.setPath("/");
//
//        cookie.setMaxAge(-1);
//
//
//        response.addCookie(cookie);
    }

    private void writeCookie(HttpServletResponse response, String token) {
        Cookie cookie = new Cookie(JwtConstants.COOKIE_NAME, token);
        // cookie的作用域
        cookie.setDomain(JwtConstants.DOMAIN);
        // 是否禁止JS操作cookie，避免XSS攻击
        cookie.setHttpOnly(true);
        // cookie有效期，-1就是跟随当前会话，浏览器关闭就消失
        cookie.setMaxAge(-1);
        // cookie作用的路径，/代表一切路径
        cookie.setPath("/");
        response.addCookie(cookie);
    }

    @Override
    public String verify(HttpServletRequest request) {

        String token = CookieUtils.getCookieValue(request, JwtConstants.COOKIE_NAME);

        //错误的可能1，token本身非法，2，没有修改过但是过期了
        UserDetail userDetail;
        try {
            userDetail = jwtUtils.parseJwt(token).getUserDetail();
        } catch (Exception e) {
            throw new LyException(401, "用户未登录");
        }
        return userDetail.getUsername();
    }


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        String token = CookieUtils.getCookieValue(request, JwtConstants.COOKIE_NAME);

        //错误的可能1，token本身非法，2，没有修改过但是过期了
        Long userId;
        try {
            userId = jwtUtils.parseJwt(token).getUserDetail().getId();
        } catch (Exception e) {
            throw new LyException(401, "用户未登录");
        }
        //
        // 4.如果有效，删除cookie（重新写一个cookie，maxAge为0）
        CookieUtils.deleteCookie(JwtConstants.COOKIE_NAME, JwtConstants.DOMAIN, response);

        this.redisTemplate.delete(RedisConstants.JTI_KEY_PREFIX + userId);
    }
}
